﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace DeploymentMaxLib.Actions
{
    public class ActionHosts : ActionBase
    {
        /// <summary>
        /// 
        /// </summary>
        public override string LongName
        {
            get { return Common.Constants.LongName; }
        }

        public override string Description
        {
            get { return Common.Constants.Description; }
        }

        public override ActionResponse Execute(ActionRequest pActionRequest)
        {
            base.Result = Validate(pActionRequest);

            if (!base.Result.HasErrorOrCritical())
            {
                var tExecutionType = pActionRequest.ExecutionType.ToEnum<Common.ExecutionType>();

                switch (tExecutionType)
                {
                    case Common.ExecutionType.AddHostEntry:
                        {

                        } break;
                }
            }

            return pActionRequest.GetResponse(this);
        }

        public class HostsParser
        {
            public const string RegExIPHostFormat = @"^(\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3})(.*)";

            public abstract class HostValueBase
            {
                public abstract string Value { get; }
            }

            public class HostValueComment : HostValueBase
            {
                private string comment = "";

                public string Comment
                {
                    get { return comment; }
                    set { comment = value; }
                }

                public override string Value
                {
                    get
                    {
                        var val = Comment;
                        if (val.Length != 0 && val[0] != '#')
                            val = "#" + val;
                        return val;
                    }
                }
            }

            public class HostValueEntry : HostValueBase
            {
                private string ipAddress = "";
                private string hostName = "";

                public string IPAddress { get { return ipAddress; } set { ipAddress = value.Trim(); } }
                public string HostName { get { return hostName; } set { hostName = value.Trim(); } }
                public override string Value { get { return string.Format("{0}\t{1}", IPAddress, HostName); } }
            }

            public List<HostValueBase> HostValueList = new List<HostValueBase>();

            public static HostsParser ParseFile(string pHostFile)
            {
                var tHostParser = new HostsParser();

                using (var sr = new System.IO.StreamReader(pHostFile))
                {
                    while (!sr.EndOfStream)
                    {
                        var line = sr.ReadLine();
                        if (System.Text.RegularExpressions.Regex.IsMatch(line, HostsParser.RegExIPHostFormat))
                        {
                            var array = System.Text.RegularExpressions.Regex.Replace(line, HostsParser.RegExIPHostFormat, @"$1\t$2").Split('\t');

                            tHostParser.HostValueList.Add(new HostValueEntry() { HostName = array[1], IPAddress = array[0] });
                        }
                        else
                        {
                            tHostParser.HostValueList.Add(new HostValueComment() { Comment = line });
                        }
                    }
                }

                return tHostParser;
            }

            public void AddHostEntry(string pIPAddress, string pHostName, string pHeaderComment)
            {
                var tHostValueList = HostValueList.FindAll(t => t is HostValueEntry).Cast<HostValueEntry>();

                var tDuplicate = tHostValueList.Count() != 0;

                if (tDuplicate)
                {
                    tDuplicate = tHostValueList.Single(t => t.IPAddress == pIPAddress.Trim() && t.HostName.Equals(pHostName.Trim(), StringComparison.CurrentCultureIgnoreCase)) != null;
                }

                if (!tDuplicate)
                {
                    HostValueList.Add(new HostValueEntry() { HostName = pHostName, IPAddress = pIPAddress });
                }
            }

            public void DeleteHostEntry(string pIPAddress, string pHostName, string pHeaderComment)
            {
                var tHostValueList = HostValueList.FindAll(t => t is HostValueEntry).Cast<HostValueEntry>();

                var tDelete = tHostValueList.Count() != 0;

                if (tDelete)
                {
                    var tHostValue = tHostValueList.Single(t => t.IPAddress == pIPAddress.Trim() && t.HostName.Equals(pHostName.Trim(), StringComparison.CurrentCultureIgnoreCase));

                    HostValueList.Remove(tHostValue);
                }
            }

            public void UpdateIPAddressByHostName(string pHostName, string pIPAddress)
            {
                var tHostValueList = HostValueList.FindAll(t => t is HostValueEntry).Cast<HostValueEntry>();

                var tDuplicate = tHostValueList.Count() != 0;

                if (tDuplicate)
                {
                    var tHostValue = tHostValueList.FirstOrDefault(t => t.HostName.Equals(pHostName.Trim(), StringComparison.CurrentCultureIgnoreCase));

                    if (tHostValue != null)
                    {
                        tHostValue.IPAddress = pIPAddress;
                    }
                }
            }
        }

        public static class Common
        {
            public enum ExecutionType
            {
                None = 0,
                AddHostEntry = 1,
                DeleteHostEntry = 2,
                UpdateIPAddressByHostName = 3
            }

            public static class Constants
            {
                public const string LongName = "Hosts File";
                public const string Description = "Modify Hosts file by adding, updating and removing entries.";

            }
        }

        public override ActionResult Validate(ActionRequest pRequest)
        {
            var tResult = new ActionResult();

            return tResult;
        }
    }
}